<!--
    CustomTable 组件说明文档
    功能：基于ElementUI Table封装的增强型表格组件，支持动态列显隐、操作列自定义、序号列等功能
    特色：
    1. 支持列动态显示/隐藏控制
    2. 内置可定制的操作按钮列
    3. 自动合并默认列配置
    4. 支持自定义列模板插槽
    5. 支持自定义操作按钮列
    6. 支持自定义翻页布局
-->
<template>
    <div class="custom-table-container">
        <!-- 主表格结构 -->
        <el-table v-if="isshow" :ref="innerTableRef" :data="tableData" v-bind="$attrs" :default-sort="defaultSort"
            :show-summary="showSummary" :summary-method="summaryMethod" :border="border" :size="size"
            @row-click="$emit('row-click', $event)" @selection-change="$emit('selection-change', $event)"
            @header-dragend="(newWidth, oldWidth, column) => {
            const colProp = column.property
            const targetCol = this.columns.find(c => c.prop === colProp)
            if (targetCol) {
                targetCol.width = newWidth
                this.saveColumnState()
            }
        }">
            <!-- <el-table-column v-for="col in processedColumns" :key="col.prop" v-bind="col">
                <template #header="{ column }">
                    <div class="column-header">
                        <span>{{ column.label }}</span>
                        <el-tooltip v-if="!col.fixed" effect="dark" content="拖拽排序" placement="top">
                            <i class="drag-handle el-icon-s-fold" @mousedown.stop></i>
                        </el-tooltip>
                    </div>
                </template>
</el-table-column> -->

            <!-- 多选列：当selection为true时显示 -->
            <el-table-column v-if="selection" type="selection" width="55">
            </el-table-column>

            <!-- 序号列：当showIndexColumn为true时显示 -->
            <el-table-column v-if="showIndexColumn" fixed type="index" label="序号" width="50" />

            <!-- 动态列渲染：根据processedColumns生成可配置列 -->
            <template v-for="col in processedColumns">
                <!-- 单列定义：visible属性控制列显示 -->
                <el-table-column :key="col.prop" v-bind="col" :fixed="col.fixed" :sortable="col.sortable"
                    v-if="col.visible">
                    <!-- 列内容渲染逻辑 -->
                    <template slot-scope="scope">
                        <!-- 优先使用具名插槽 -->
                        <slot v-if="col.slotName" :name="col.slotName" v-bind="scope" />
                        <template v-else>
                            <!-- 格式化显示或直接显示数据 -->
                            <span v-if="col.formatter">
                                {{ col.formatter(scope.row) }}
                            </span>
                            <template v-else>
                                {{ scope.row[col.prop] }}
                            </template>
                        </template>
                    </template>
                </el-table-column>
            </template>

            <!-- 操作列：当showActionColumn为true时显示 -->
            <el-table-column v-if="showActionColumn" label="操作" fixed="right" width="180">
                <!-- 自定义表头（包含列显隐控制） -->
                <template #header>
                    <div class="flex align-items-center" style="height: 46px">
                        <span class="e-flex-1">操作</span>
                        <!-- 列显隐控制下拉菜单 -->
                        <el-dropdown :hide-on-click="false" split-button size="mini" type="primary">
                            字段显示
                            <template #dropdown>
                                <el-dropdown-menu>
                                    <!-- 动态生成列显隐复选框 -->
                                    <el-dropdown-item v-for="col in processedColumns" :key="col.prop">
                                        <el-checkbox v-model="localColumnStates[col.prop]" @change="saveColumnState"
                                            :aria-label="`切换${col.label}列显示`">
                                            {{ col.label }}
                                        </el-checkbox>
                                    </el-dropdown-item>
                                </el-dropdown-menu>
                            </template>
                        </el-dropdown>
                    </div>
                </template>

                <!-- 操作按钮区域 -->
                <template #default="scope">
                    <slot name="actions" v-bind="scope">
                        <!-- 默认操作按钮渲染逻辑 -->
                        <template v-for="action in actions">
                            <el-button :key="action.name" type="text" size="small"
                                @click.stop="handleAction(action.name, scope.row, $event)"
                                v-if="isActionVisible(action, scope.row)">
                                {{ action.label }}
                            </el-button>
                        </template>
                    </slot>
                </template>
            </el-table-column>
        </el-table>
        <!-- 翻页 -->
        <div class="table-pagination">
            <el-pagination v-if="showPagination" background :layout="paginationLayout" :total="innerTotal"
                :page-sizes="pageSizes" :page-size="innerPageSize" :current-page="innerPageIndex"
                @size-change="handleSizeChange" @current-change="handlePageChange">
            </el-pagination>
        </div>
    </div>
</template>

<script>
import Sortable from 'sortablejs' // 引入拖拽排序插件

export default {
    name: 'ColumnTable',
    props: {
        /* 尺寸 */
        size: {
            type: String,
            default: 'default'
        },
        /* 组件ref名 */
        innerTableRef: {
            type: String,
            default: 'elTable'
        },
        /** 表格数据源 */
        tableData: {
            type: Array,
            required: true
        },
        /** 列配置数组，支持参数：
         * {
         *   prop: 字段名,
         *   label: 列标题,
         *   visible: 是否可见,
         *   width: 列宽,
         *   fixed: 固定位置,
         *   formatter: 数据格式化函数,
         *   slotName: 自定义插槽名
         * } 
         */
        columns: {
            type: Array,
            default: () => [],
            // 移除columns配置中的visible要求
            validator: arr => arr.every(col => 'prop' in col && 'label' in col)
        },
        /** 操作按钮配置数组：
         * {
         *   name: 操作标识,
         *   label: 显示文本,
         *   visible: 显示条件函数/布尔值
         * }
         */
        actions: {
            type: Array,
            default: () => []
        },
        /** 是否显示序号列 */
        showIndexColumn: {
            type: Boolean,
            default: true
        },
        /** 是否显示操作列 */
        showActionColumn: {
            type: Boolean,
            default: true
        },
        /* 新增配置项：是否开启状态持久化 */
        persistColumns: {
            type: Boolean,
            default: true
        },
        /* 新增配置项：存储唯一标识 */
        storageKey: {
            type: String,
            default: () => {
                if (process.client) {
                    return window.location.pathname
                }
            }
        },
        /** 是否显示汇总行 */
        showSummary: {
            type: Boolean,
            default: false
        },

        /** 汇总计算方法 */
        summaryMethod: {
            type: Function,
            default: null
        },
        /** 
         * 默认排序配置 
         * @example {prop: 'date', order: 'ascending'}
        */
        defaultSort: {
            type: Object,
            default: () => ({}),
            // validator: val => !val || (val.prop && ['ascending', 'descending'].includes(val.order))
        },
        /* 是否多选 */
        selection: {
            type: Boolean,
            default: false
        },
        /* 是否有边框 */
        border: {
            type: Boolean,
            default: true
        },
        /** 
         * 新增分页相关props 
        */
        showPagination: {
            type: Boolean,
            default: true
        },
        paginationLayout: {
            type: String,
            default: 'sizes, total, prev, pager, next'
        },
        pageSizes: {
            type: Array,
            default: () => [10, 50, 100, 200]
        },
        pageSize: {
            type: Number,
            default: 10
        },
        pageIndex: {
            type: Number,
            default: 1
        },
        total: {
            type: Number,
            default: 0
        }
    },
    computed: {
        /**
         * 处理后的列配置，合并默认值：
         * - visible: 默认true
         * - width: 默认100px
         */
        processedColumns() {
            const orderedColumns = this.applyColumnOrder(this.columns)
            return orderedColumns.map(col => ({
                width: 100,
                visible: this.localColumnStates[col.prop] ?? true,
                ...col
            }))
        }
    },
    // 新增watch
    watch: {
        columns: {
            deep: true,
            handler(newVal) {
                this.applySavedWidths(newVal)
            }
        },
        processedColumns: {
            deep: true,
            handler() {
                this.saveColumnState()
            }
        },
        pageSize(val) {
            this.innerPageSize = val
        },
        pageIndex(val) {
            this.innerPageIndex = val
        },
        total(val) {
            this.innerTotal = val
        }
    },
    data() {
        return {
            // 新增内部状态管理
            localColumnStates: {},
            innerPageSize: this.pageSize,
            innerPageIndex: this.pageIndex,
            innerTotal: this.total,
            /* 拖拽排序相关状态 */
            columnOrder: [],
            isshow: true,
        }
    },
    created() {
        // 初始化时加载存储状态
        this.initColumnStates()
        // 初始化时加载列宽
        this.initColumnWidths()
        // 初始化列排序
        this.initColumnSortable()
    },
    methods: {
        /** 处理操作按钮点击事件 */
        handleAction(actionName, row, event) {
            this.$emit('action-click', { action: actionName, row, event })
        },
        /** 判断操作按钮是否可见 */
        isActionVisible(action, row) {
            return typeof action.visible === 'function'
                ? action.visible(row)
                : action.visible ?? true
        },
        // 新增初始化拖拽排序方法
        initColumnSortable() {
            if (process.client) {
                this.isshow = false
                this.$nextTick(() => {
                    this.isshow = true
                    setTimeout(() => {
                        const wrapper = document.querySelector('.el-table__header-wrapper tr')
                        if (!wrapper) return

                        this.sortable = Sortable.create(wrapper, {
                            animation: 150,
                            handle: '.cell', // 拖拽手柄
                            onEnd: ({ oldIndex, newIndex }) => {
                                this.handleColumnSort(oldIndex, newIndex)
                            }
                        })
                    }, 100)
                })
            }
            // if (!process.client) return

            // // 使用ref获取表格实例
            // const tableRef = this.$refs[this.innerTableRef]
            // if (!tableRef) return

            // // 使用$nextTick确保DOM渲染完成
            // this.$nextTick(() => {
            //     // 通过表格实例获取header wrapper
            //     const wrapper = tableRef.$el.querySelector('.el-table__header-wrapper tr')
            //     if (!wrapper) return

            //     // 销毁旧实例避免内存泄漏
            //     if (this.sortable) this.sortable.destroy()

            //     // 使用更精准的选择器
            //     this.sortable = Sortable.create(wrapper, {
            //         animation: 150,
            //         handle: '.el-table__cell:not(.is-hidden) > .cell', // 排除隐藏列
            //         filter: '.is-fixed', // 过滤固定列
            //         onEnd: ({ oldIndex, newIndex }) => {
            //             this.handleColumnSort(oldIndex, newIndex)
            //         }
            //     })
            // })
        },

        // 新增处理排序逻辑
        handleColumnSort(oldIndex, newIndex) {
            // 计算左侧固定列数量（多选列 + 序号列）
            const leftFixedCount = [this.selection, this.showIndexColumn].filter(Boolean).length

            // 计算右侧固定列数量（操作列）
            const rightFixedCount = this.showActionColumn ? 1 : 0

            // 排除左右固定列的索引范围
            const validMaxIndex = this.processedColumns.length - 1 - rightFixedCount
            const adjustedOldIndex = oldIndex - leftFixedCount
            const adjustedNewIndex = newIndex - leftFixedCount

            // 边界检查
            if (adjustedOldIndex < 0 ||
                adjustedNewIndex < 0 ||
                adjustedOldIndex > validMaxIndex ||
                adjustedNewIndex > validMaxIndex) return

            // 获取实际可见列
            const visibleColumns = this.processedColumns.filter((item) => item.visible == true)

            // 创建新列顺序
            const newColumns = [...visibleColumns]
            const [movedColumn] = newColumns.splice(adjustedOldIndex, 1)
            newColumns.splice(adjustedNewIndex, 0, movedColumn)

            // 合并右侧固定列
            const finalColumns = [
                ...newColumns,
                // ...this.processedColumns.slice(-rightFixedCount).filter(col => col.visible)
            ]

            // 更新排序状态
            this.columnOrder = finalColumns.map(col => col.prop)
            this.saveColumnState()

            this.$emit('column-sort', {
                oldIndex,
                newIndex,
                oldColumn: visibleColumns[adjustedOldIndex],
                newColumn: visibleColumns[adjustedNewIndex]
            })

            this.initColumnSortable()

            console.log('实际拖动顺序:',
                `从 ${visibleColumns[adjustedOldIndex]?.prop}`,
                `到 ${visibleColumns[adjustedNewIndex]?.prop}`
            )
        },
        // 应用列排序
        applyColumnOrder(columns) {
            // 添加空值检查
            if (!Array.isArray(columns)) return [];

            // 合并默认顺序和保存顺序
            const defaultOrder = columns.map(col => col.prop)
            const savedOrder = Array.isArray(this.columnOrder) ? this.columnOrder : []

            // 创建有效排序列表（过滤不存在的列）
            const validOrder = savedOrder.filter(prop =>
                defaultOrder.includes(prop)
            )

            // 添加新增列到末尾
            const newColumns = defaultOrder.filter(prop =>
                !validOrder.includes(prop)
            )

            return [...validOrder, ...newColumns]
                .map(prop => columns.find(col => col.prop === prop))
                .filter(Boolean) // 过滤undefined
        },
        // 初始化列宽
        initColumnWidths() {
            if (process.client && this.persistColumns) {
                const saved = JSON.parse(localStorage.getItem(this.storageKey) || '{}')
                this.columns.forEach(col => {
                    if (saved[col.prop]?.width) {
                        this.$set(col, 'width', saved[col.prop].width)
                    }
                })
            }
        },

        // 应用保存的列宽
        applySavedWidths(columns) {
            if (process.client && this.persistColumns) {
                const saved = JSON.parse(localStorage.getItem(this.storageKey) || '{}')
                columns.forEach(col => {
                    if (saved[col.prop]?.width) {
                        this.$set(col, 'width', saved[col.prop].width)
                    }
                })
            }
        },

        // 修改保存状态方法
        saveColumnState() {
            if (process.client && this.persistColumns) {
                const stateToSave = {
                    order: this.columnOrder,
                    states: this.columns.reduce((acc, col) => {
                        acc[col.prop] = {
                            visible: !!this.localColumnStates[col.prop],
                            width: Number(col.width) || null
                        }
                        return acc
                    }, {})
                }

                localStorage.setItem(this.storageKey, JSON.stringify(stateToSave))
            }
        },
        // 初始化列状态
        initColumnStates() {
            if (process.client) {
                const stored = this.persistColumns
                    ? JSON.parse(localStorage.getItem(this.storageKey) || '{}')
                    : {}

                // 初始化列顺序
                this.columnOrder = Array.isArray(stored.order) ? stored.order : [];

                // 原有初始化逻辑修改
                if (Array.isArray(this.columns)) {
                    this.columns.forEach(col => {
                        const storedState = stored.states?.[col.prop] || {
                            visible: col.visible !== undefined ? col.visible : true,
                            width: Number(col.width) || 'auto'
                        }

                        this.$set(this.localColumnStates, col.prop, storedState.visible)
                        this.$set(col, 'width', storedState.width)
                    })
                }

            }
        },
        /**  获取本地存储的列显示状态 **/
        getStoredState(prop) {
            if (process.client) {
                if (!this.persistColumns) return null
                const saved = localStorage.getItem(this.storageKey)
                return saved ? JSON.parse(saved)[prop] : null
            }
        },
        handlePageChange(page) {
            this.innerPageIndex = page
            this.$emit('page-change', {
                pageIndex: page,
                pageSize: this.innerPageSize
            })
        },
        handleSizeChange(size) {
            this.innerPageSize = size
            this.$emit('page-change', {
                pageIndex: this.innerPageIndex,
                pageSize: size
            })
        }
    }
}
</script>

<style scoped>
/* 拖拽手柄样式 */
.el-table__header-wrapper th {
    cursor: move;
    user-select: none;
    transition: background-color 0.3s;
}

.el-table__header-wrapper th.sortable-ghost {
    background: #f5f7fa;
}

.el-button.el-button--text.el-button--small {
    position: relative;
}

.el-button.el-button--text.el-button--small+.el-button.el-button--text.el-button--small:after {
    content: '';
    border-left: 1px solid #dbdbdb;
    position: absolute;
    left: -7px;
    top: 10px;
    height: 10px;
}

/* 添加样式 */
.column-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    height: 100%;
}

.drag-handle {
    cursor: move;
    color: #909399;
    opacity: 0;
    transition: opacity 0.3s;
    margin-left: 8px;
}

.el-table__header-wrapper th:hover .drag-handle {
    opacity: 1;
}

/* 固定列不显示拖拽手柄 */
.el-table__fixed-right .drag-handle,
.el-table__fixed .drag-handle {
    display: none !important;
}
</style>